import { AccountConfig } from './ctpConfig';

// 账号配置管理器
export class AccountConfigManager {
  private static readonly ACCOUNTS_CONFIG_FILE = 'accounts_config.xml';
  private static readonly STORAGE_KEY = 'account_configs';

  // 获取所有账号配置
  static async getAllAccounts(): Promise<Record<string, AccountConfig>> {
    try {
      // 优先从config文件夹的XML文件读取
      const xmlAccounts = await this.loadAccountsFromXML();
      if (xmlAccounts && Object.keys(xmlAccounts).length > 0) {
        return xmlAccounts;
      }

      // 如果XML文件不存在或为空，从localStorage读取
      const stored = localStorage.getItem(this.STORAGE_KEY);
      if (stored) {
        return JSON.parse(stored);
      }

      return {};
    } catch (error) {
      return {};
    }
  }

  // 保存账号配置
  static async saveAccount(accountConfig: AccountConfig): Promise<void> {
    try {
      // 获取现有配置
      const accounts = await this.getAllAccounts();

      // 添加或更新账号配置
      accounts[accountConfig.accountName] = {
        ...accountConfig,
        updateTime: new Date().toISOString()
      };

      // 保存到config文件夹的XML文件
      await this.saveAccountsToXML(accounts);

      // 同时保存到localStorage作为备份
      localStorage.setItem(this.STORAGE_KEY, JSON.stringify(accounts));
    } catch (error) {
      throw error;
    }
  }

  // 删除账号配置
  static async deleteAccount(accountName: string): Promise<void> {
    try {
      const accounts = await this.getAllAccounts();
      delete accounts[accountName];

      // 保存到config文件夹的XML文件
      await this.saveAccountsToXML(accounts);

      // 同时更新localStorage
      localStorage.setItem(this.STORAGE_KEY, JSON.stringify(accounts));

    } catch (error) {
      throw error;
    }
  }

  // 获取单个账号配置
  static async getAccount(accountName: string): Promise<AccountConfig | null> {
    try {
      const accounts = await this.getAllAccounts();
      return accounts[accountName] || null;
    } catch (error) {
      return null;
    }
  }

  // 验证账号配置
  static validateAccount(config: Partial<AccountConfig>): string[] {
    const errors: string[] = [];

    if (!config.accountName?.trim()) {
      errors.push('请输入账户名');
    }

    if (!config.tradeFront?.trim()) {
      errors.push('请输入交易服务器前置地址');
    }

    if (!config.marketFront?.trim()) {
      errors.push('请输入行情服务前置地址');
    }

    if (!config.brokerName?.trim()) {
      errors.push('请输入期货公司名称');
    }

    // if (!config.brokerId?.trim()) {
    //   errors.push('请输入期货公司代码');
    // }

    // 验证地址格式
    const frontRegex = /^tcp:\/\/[\d.]+:\d+$/;
    if (config.tradeFront && !frontRegex.test(config.tradeFront)) {
      errors.push('交易前置地址格式不正确，应为: tcp://ip:port');
    }

    if (config.marketFront && !frontRegex.test(config.marketFront)) {
      errors.push('行情前置地址格式不正确，应为: tcp://ip:port');
    }

    return errors;
  }

  // 从config文件夹的XML文件加载账号配置
  private static async loadAccountsFromXML(): Promise<Record<string, AccountConfig> | null> {
    try {
      const { invoke } = await import('@tauri-apps/api/core');

      // 从config文件夹读取XML文件内容
      const xmlContent = await invoke('read_config_file', { filename: this.ACCOUNTS_CONFIG_FILE });

      // 解析XML内容
      return this.parseAccountsXML(xmlContent as string);
    } catch (error) {
      return null;
    }
  }

  // 保存账号配置到config文件夹的XML文件
  private static async saveAccountsToXML(accounts: Record<string, AccountConfig>): Promise<void> {
    try {
      const { invoke } = await import('@tauri-apps/api/core');

      // 生成XML内容
      const xmlContent = this.generateAccountsXML(accounts);

      // 保存到config文件夹
      const savedPath = await invoke('save_config_file', {
        filename: this.ACCOUNTS_CONFIG_FILE,
        content: xmlContent
      });

    } catch (error) {
      throw error;
    }
  }

  // 解析XML内容
  private static parseAccountsXML(xmlContent: string): Record<string, AccountConfig> {
    const accounts: Record<string, AccountConfig> = {};

    try {
      // 提取所有的account标签
      const accountMatches = xmlContent.match(/<account[^>]*>[\s\S]*?<\/account>/g);

      if (accountMatches) {
        accountMatches.forEach(accountXml => {
          const extractValue = (tag: string) => {
            const match = accountXml.match(new RegExp(`<${tag}>(.*?)<\/${tag}>`));
            return match ? match[1] : '';
          };

          const accountName = extractValue('accountName');
          if (accountName) {
            accounts[accountName] = {
              accountName,
              tradeFront: extractValue('tradeFront'),
              marketFront: extractValue('marketFront'),
              brokerName: extractValue('brokerName'),
              brokerId: extractValue('brokerId'),
              createTime: extractValue('createTime'),
              updateTime: extractValue('updateTime')
            };
          }
        });
      }
    } catch (error) {
    }

    return accounts;
  }

  // 生成XML内容
  private static generateAccountsXML(accounts: Record<string, AccountConfig>): string {
    let xml = `<?xml version="1.0" encoding="UTF-8"?>
<accounts>`;

    Object.values(accounts).forEach(account => {
      xml += `
  <account>
    <accountName>${account.accountName}</accountName>
    <tradeFront>${account.tradeFront}</tradeFront>
    <marketFront>${account.marketFront}</marketFront>
    <brokerName>${account.brokerName}</brokerName>
    <brokerId>${account.brokerId}</brokerId>
    <createTime>${account.createTime}</createTime>
    <updateTime>${account.updateTime}</updateTime>
  </account>`;
    });

    xml += `
</accounts>`;

    return xml;
  }

  // 将账号配置转换为CTP服务器配置格式
  static accountToCtpConfig(account: AccountConfig): any {
    return {
      name: account.brokerName, // 使用公司名称作为显示名称
      brokerId: account.brokerId,
      tradeFront: account.tradeFront,
      marketFront: account.marketFront,
      accountName: account.accountName, // 保留账户名用于标识
    };
  }

  // 获取账号配置作为CTP服务器选项
  static async getAccountsAsCtpServers(): Promise<Record<string, any>> {
    try {
      const accounts = await this.getAllAccounts();
      const ctpServers: Record<string, any> = {};

      Object.values(accounts).forEach(account => {
        ctpServers[account.accountName] = this.accountToCtpConfig(account);
      });

      return ctpServers;
    } catch (error) {
      return {};
    }
  }
}
